import random
import time
from threading import Thread, Barrier, BrokenBarrierError
from common.utility import Utility

def main(parties: int = 5, timeout: float = 5) -> None:
    global  barrier
    Utility.print_info('create barrier.')
    barrier = Barrier(parties, callback_action, timeout)
    create_threads(parties, timeout)

def create_threads(parties: int, timeout: float) -> None:
    for idx in range(parties):
        Thread(target=task, args=(timeout,)).start()

def task(timeout: float) -> None:
    Utility.print_info('entered.')
    sleep_time: float = random.random()*(timeout+1)
    Utility.print_info(f'parties:{barrier.parties}, n_waiting:{barrier.n_waiting}, sleep time:{sleep_time}.')
    time.sleep(sleep_time)
    try:
        barrier.wait()
    except BrokenBarrierError as err:
        Utility.print_info(f'barrier broken:{err}')
    finally:
        Utility.print_info(f'is broken:{barrier.broken}, parties:{barrier.parties}, n_waiting:{barrier.n_waiting}.')
        Utility.print_info('exited.')


def callback_action() -> None:
    Utility.print_info('barrier callback function.')

barrier: Barrier
main(3)